import re
from django.contrib.auth import login, authenticate, logout
from django.http import JsonResponse
from django.views import View
from apps.users.models import User, Address
import json
from apps.users.utils import generic_email_verify_token, check_verify_token
from utils.views import LoginRequiredJSONMixin
from celery_tasks.email.tasks import celery_send_email

"""
需求分析：根据页面的功能，从上到下，从左到右，哪些功能需要和后端配合
如何确定，哪些功能需要和后端交互
        1、经验
        2、关注类似网站的相似功能

"""
"""
判断用户名是否重复的功能

前端（了解）：当用户输入用户名后，失去焦点，发送一个axios（ajax）请求

后端（思路）：

    请求：接受用户名
    业务逻辑：根据用户名查询数据库，如果查询结果为0，没有注册；查询结果为1，说明有注册。
    响应：JSON，{code：0，count：0/1...}
    路由： GET     /usernames/<username>/count/
    
"""


class UsernameCountView(View):

    def get(self, request, username):
        # 步骤：
        # 1、接受用户名，判断用户名
        # if not re.match('[a-zA-Z0-9_-]{5,20}', username):  # 采用路由转换器
        #     return JsonResponse({'code': 0, 'errmsg': '用户名不满足需求'})
        # 2、根据用户名查询数据库
        count = User.objects.filter(username=username).count()
        # # 3、返回响应
        return JsonResponse({'code': 0, 'count': count, 'errmsg': 'ok'})


class MobileCountView(View):

    def get(self, request, mobile):
        count = User.objects.filter(mobile=mobile).count()

        return JsonResponse({'code': 0, 'count': count, 'errmsg': 'OK'})


"""
前端：用户输入后发送axios请求
后端：接收请求（json），获取数据；验证数据，数据入库；响应（json）
路由：post register/

"""


class RegisterView(View):

    def post(self, request):
        # 接受请求
        body_dict = json.loads(request.body.decode())
        # body_bytes = request.body
        # body_str = body_bytes.decode()
        # body_dict = json.loads(body_str)
        # 获取数据
        username = body_dict.get('username')
        password = body_dict.get('password')
        password2 = body_dict.get('password2')
        mobile = body_dict.get('mobile')
        allow = body_dict.get('allow')
        # 验证数据
        if not all([username, password, password2, mobile, allow]):
            return JsonResponse({'code': 400, 'errmsg': '参数不全'})
        if not re.match('[a-zA-Z0-9_-]{5,20}', username):
            return JsonResponse({'code': 400, 'errmsg': '用户名格式有误'})
        if not re.match('[0-9A-Za-z]{8,20}', password):
            return JsonResponse({'code': 400, 'errmsg': '密码格式不对'})
        if password != password2:
            return JsonResponse({'code': 400, 'errmsg': '输入密码不一致'})
        if not re.match('1[3-9]\\d{9}', mobile):
            return JsonResponse({'code': 400, 'errmsg': '手机号不正确'})
        if not allow:
            return JsonResponse({'code': 400, 'errmsg': '协议未勾选'})
        # 数据入库
        user = User.objects.create_user(username=username,
                                        password=password,
                                        mobile=mobile)
        login(request, user)
        # 返回响应
        return JsonResponse({'code': 0, 'errmsg': 'OK'})


"""
注册成功即登录
注册成功转到登录页面
"""


class LoginView(View):

    def post(self, request, ):
        data = json.loads(request.body.decode())
        username = data.get('username')
        password = data.get('password')
        remembered = data.get('remembered')
        if not all([username, password]):
            return JsonResponse({'code': 400, 'errmsg': '参数不全'})
        if re.match('1[3-9]\\d{9}', username):
            # 实现手机号登录
            User.USERNAME_FIELD = 'mobile'
        else:
            # 实现用户名登录
            User.USERNAME_FIELD = 'username'
        user = authenticate(username=username, password=password)
        if user is None:
            return JsonResponse({'code': 400, 'errmsg': '账号或者密码错误'})
        login(request, user)
        if remembered:
            request.session.set_expiry(None)
        else:
            request.session.set_expiry(0)
        response = JsonResponse({'code': 0, 'errmsg': 'OK'})
        # 首页显示用户信息
        response.set_cookie('username', username)
        return response


class LogoutView(View):

    def delete(self, request):
        logout(request)
        # 删除session信息
        response = JsonResponse({'code': 0, 'errmsg': 'OK'})
        # 删除cookie信息
        response.delete_cookie('username')
        return response


class CenterView(LoginRequiredJSONMixin, View):

    def get(self, request):
        info_data = {
            'username': request.user.username,
            'email': request.user.email,
            'mobile': request.user.mobile,
            'email_active': request.user.email_active,
        }
        return JsonResponse({'code': 0,
                             'errmsg': 'OK',
                             'info_data': info_data})


class EmailView(LoginRequiredJSONMixin, View):

    def put(self, request):
        data = json.loads(request.body.decode())
        email = data.get('email')
        # TODO 验证邮箱
        user = request.user
        user.email = email
        user.save()
        subject = '美多商城邮箱激活'
        message = ""
        from_email = '美多商城<yuzhihao0522@163.com>'
        recipient_list = ['yuzhihao0522@163.com']
        token = generic_email_verify_token(request.user.id)
        verify_url = "http://www.meiduo.site:8080/success_verify_email.html?token=%s" % token
        html_message = '<p>尊敬的用户您好！</p>' \
                       '<p>感谢您使用美多商城。</p>' \
                       '<p>您的邮箱为：%s 。请点击此链接激活您的邮箱：</p>' \
                       '<p><a href="%s">%s</a></p>' % (email, verify_url, verify_url)

        celery_send_email.delay(subject=subject,
                                message=message,
                                from_email=from_email,
                                recipient_list=recipient_list,
                                html_message=html_message)

        return JsonResponse({'code': 0, 'errmsg': 'OK'})


class EmailVerifyView(View):

    def put(self, request):
        token = request.GET.get('token')
        if token is None:
            return JsonResponse({'code': 400, 'errmsg': '参数缺失'})
        user_id = check_verify_token(token)
        if user_id is None:
            return JsonResponse({'code': 400, 'errmsg': '参数错误'})
        user = User.objects.get(id=user_id)
        user.email_active = True
        user.save()
        return JsonResponse({'code': 0, 'errmsg': 'OK'})


class AddressCreateView(LoginRequiredJSONMixin, View):

    def post(self, request):
        data = json.loads(request.body.decode())
        receiver = data.get('receiver')
        province_id = data.get('province_id')
        city_id = data.get('city_id')
        district_id = data.get('district_id')
        place = data.get('place')
        mobile = data.get('mobile')
        tel = data.get('tel')
        email = data.get('email')
        user = request.user
        # TODO 验证必传参数
        address = Address.objects.create(
            user=user,
            title=receiver,
            receiver=receiver,
            province_id=province_id,
            city_id=city_id,
            district_id=district_id,
            place=place,
            mobile=mobile,
            tel=tel,
            email=email
        )

        address_dict = {
            "id": address.id,
            "title": address.title,
            "receiver": address.receiver,
            "province": address.province.name,
            "city": address.city.name,
            "district": address.district.name,
            "place": address.place,
            "mobile": address.mobile,
            "tel": address.tel,
            "email": address.email
        }
        return JsonResponse({'code': 0, 'errmsg': 'OK', 'address': address_dict})


class AddressView(LoginRequiredJSONMixin, View):

    def get(self, request):
        addresses = Address.objects.filter(user=request.user,
                                           is_deleted=False)
        address_list = []
        for address in addresses:
            address_list .append({
                "id": address.id,
                "title": address.title,
                "receiver": address.receiver,
                "province": address.province.name,
                "city": address.city.name,
                "district": address.district.name,
                "place": address.place,
                "mobile": address.mobile,
                "tel": address.tel,
                "email": address.email
            })

        return JsonResponse({'code': 0,
                             'errmsg': 'OK',
                             'addresses': address_list
                             })









